{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 在线性回归模型中使用梯度下降法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.random.seed(666)\n",
    "x = 2 * np.random.random(size=100)\n",
    "y = x * 3. + 4. + np.random.normal(size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X = x.reshape(-1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.40087424],\n",
       "       [ 1.68837329],\n",
       "       [ 1.35302867],\n",
       "       [ 1.45571611],\n",
       "       [ 1.90291591],\n",
       "       [ 0.02540639],\n",
       "       [ 0.8271754 ],\n",
       "       [ 0.09762559],\n",
       "       [ 0.19985712],\n",
       "       [ 1.01613261],\n",
       "       [ 0.40049508],\n",
       "       [ 1.48830834],\n",
       "       [ 0.38578401],\n",
       "       [ 1.4016895 ],\n",
       "       [ 0.58645621],\n",
       "       [ 1.54895891],\n",
       "       [ 0.01021768],\n",
       "       [ 0.22571531],\n",
       "       [ 0.22190734],\n",
       "       [ 0.49533646]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X[:20]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 8.91412688,  8.89446981,  8.85921604,  9.04490343,  8.75831915,\n",
       "        4.01914255,  6.84103696,  4.81582242,  3.68561238,  6.46344854,\n",
       "        4.61756153,  8.45774339,  3.21438541,  7.98486624,  4.18885101,\n",
       "        8.46060979,  4.29706975,  4.06803046,  3.58490782,  7.0558176 ])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[:20]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10f185048>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用梯度下降法训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def J(theta, X_b, y):\n",
    "    try:\n",
    "        return np.sum((y - X_b.dot(theta))**2) / len(X_b)\n",
    "    except:\n",
    "        return float('inf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def dJ(theta, X_b, y):\n",
    "    res = np.empty(len(theta))\n",
    "    res[0] = np.sum(X_b.dot(theta) - y)\n",
    "    for i in range(1, len(theta)):\n",
    "        res[i] = (X_b.dot(theta) - y).dot(X_b[:,i])\n",
    "    return res * 2 / len(X_b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def gradient_descent(X_b, y, initial_theta, eta, n_iters = 1e4, epsilon=1e-8):\n",
    "    \n",
    "    theta = initial_theta\n",
    "    cur_iter = 0\n",
    "\n",
    "    while cur_iter < n_iters:\n",
    "        gradient = dJ(theta, X_b, y)\n",
    "        last_theta = theta\n",
    "        theta = theta - eta * gradient\n",
    "        if(abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):\n",
    "            break\n",
    "            \n",
    "        cur_iter += 1\n",
    "\n",
    "    return theta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X_b = np.hstack([np.ones((len(x), 1)), x.reshape(-1,1)])\n",
    "initial_theta = np.zeros(X_b.shape[1])\n",
    "eta = 0.01\n",
    "\n",
    "theta = gradient_descent(X_b, y, initial_theta, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 4.02145786,  3.00706277])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 封装我们的线性回归算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from playML.LinearRegression import LinearRegression\n",
    "\n",
    "lin_reg = LinearRegression()\n",
    "lin_reg.fit_gd(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 3.00706277])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lin_reg.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.021457858204859"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lin_reg.intercept_"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
